package zhishuang.wang.sansi.x9.protocol;

/**
 * @Author Zhishuang.Wang
 * @Date 2023/7/5 11:23
 * @Email 1406110602@qq.com
 */

import zhishuang.wang.sansi.fcms.protocol.ProtocolPackage;
import zhishuang.wang.sansi.tools.ReturnData;
import zhishuang.wang.sansi.tools.time.DateFormat;
import zhishuang.wang.sansi.x9.devinfor.DeviceInforX9;
import zhishuang.wang.sansi.x9.devinfor.DeviceInforX9Var;

import java.util.Calendar;
import java.util.Iterator;
import java.util.Map;
import java.util.TimeZone;

public class X9DeviceControl {
    public X9DeviceControl() {
    }

    private static String urgentParamCheck(String programId, String playType, String startTime, String oldPlayAction, String playTime) {
        if (programId == null) {
            return "节目ID必填";
        } else if (playType == null) {
            return "紧急插播播放类型必填";
        } else {
            int playTimeInt = Integer.valueOf(playType);
            if (playTimeInt >= 0 && playTimeInt <= 2) {
                if (playTimeInt == 1) {
                    if (startTime == null) {
                        return "紧急插播播放类型为稍后播放（1） 时，开始时间必填";
                    }

                    if (startTime.length() != 14) {
                        return "开始时间格式必须为：YYYYMMDDHHMMSS";
                    }
                }

                if (oldPlayAction == null) {
                    return "原播放内容播放动作必填";
                } else {
                    playTimeInt = Integer.valueOf(oldPlayAction);
                    if (playTimeInt >= 0 && playTimeInt <= 1) {
                        if (playTime == null) {
                            return "插播播放时长必填";
                        } else {
                            playTimeInt = Integer.valueOf(playTime);
                            return (playTimeInt < 5 || playTimeInt > 28800) && playTimeInt != 0 ? "playTime 插播播放时长 ,取值范围：0或[5,28800]" : null;
                        }
                    } else {
                        return "原播放内容播放动作,取值范围 0 - 1 ";
                    }
                }
            } else {
                return "紧急插播播放类型，取值范围 0 - 2 ";
            }
        }
    }

    private static String snapShotParamCheck(String timeInterval, String percentage) {
        if (timeInterval == null) {
            return "定时上报的时间间隔必填";
        } else {
            int percentageInt = Integer.valueOf(timeInterval);
            if (percentageInt >= 0 && percentageInt <= 65535) {
                if (percentage == null) {
                    return "报画面的缩放比例(百分比)必填";
                } else {
                    percentageInt = Integer.valueOf(percentage);
                    return percentageInt >= 0 && percentageInt <= 100 ? null : "上报画面的缩放比例(百分比) ,取值范围：0 -100";
                }
            } else {
                return "定时上报的时间间隔,取值范围：0 - 65535";
            }
        }
    }

    private static String environmentParamCheck(String sourceType, String channel, String upload, String source) {
        if (sourceType == null) {
            return "数据来源类型必填";
        } else {
            int uploadInt = Integer.valueOf(sourceType);
            if (uploadInt >= 0 && uploadInt <= 2) {
                if (channel == null) {
                    return "设备通道必填";
                } else {
                    uploadInt = Integer.valueOf(channel);
                    if (uploadInt >= 0 && uploadInt <= 1) {
                        if (upload == null) {
                            return "是否定时上报必填";
                        } else {
                            uploadInt = Integer.valueOf(upload);
                            return uploadInt >= 0 && uploadInt <= 1 ? null : "是否定时上报取值范围：0 - 1";
                        }
                    } else {
                        return "设备通道取值范围：0 - 1";
                    }
                }
            } else {
                return "数据来源类型取值范围：0 - 2";
            }
        }
    }

    private static byte[] x9UtcTimeToByte() {
        TimeZone zone = TimeZone.getTimeZone("GMT+00:00");
        Calendar cal = Calendar.getInstance(zone);
        int year = cal.get(1);
        int month = cal.get(2) + 1;
        int day = cal.get(5);
        int hour = cal.get(11);
        int minute = cal.get(12);
        int second = cal.get(13);
        int mMsecond = cal.get(14);
        byte[] yearByte = ProtocolPackage.addIntToByte(year, 2);
        byte[] mMsecondByte = ProtocolPackage.addIntToByte(mMsecond, 2);
        byte[] dataBuff = new byte[9];
        System.arraycopy(yearByte, 0, dataBuff, 0, 2);
        dataBuff[2] = (byte)(month & 255);
        dataBuff[3] = (byte)(day & 255);
        dataBuff[4] = (byte)(hour & 255);
        dataBuff[5] = (byte)(minute & 255);
        dataBuff[6] = (byte)(second & 255);
        System.arraycopy(mMsecondByte, 0, dataBuff, 7, 2);
        return dataBuff;
    }

    private static String x9UpgradeParamCheck(String taskId, String upgradeFile, String upgradeType, String upgradeTime) {
        if (taskId == null) {
            return "升级任务ID必填";
        } else if (upgradeFile == null) {
            return "升级包名称必填";
        } else if (upgradeType == null) {
            return "升级类型必须";
        } else {
            int upgradeTypeInt = Integer.valueOf(upgradeType);
            if (upgradeTypeInt >= 0 && upgradeTypeInt <= 1) {
                if (upgradeTypeInt == 1) {
                    if (upgradeTime == null) {
                        return "当升级类型为指定时间升级（1）时，升级时间必填 ";
                    }

                    if (upgradeTime.length() != 14) {
                        return "升级时间格式必须为：YYYYMMDDHHMMSS";
                    }
                }

                return null;
            } else {
                return "升级类型取值范围：0-1";
            }
        }
    }

    public static ReturnData environmentDataToX9(String deviceId, int folNum, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        DeviceInforX9Var.devX9InforMapLock.lock();
        DeviceInforX9 dix = (DeviceInforX9) DeviceInforX9Var.devX9InforMap.get(deviceId);
        DeviceInforX9Var.devX9InforMapLock.unlock();
        if (dix != null && dix.getOnlineFlag() == 1) {
            byte[] dataBuff = new byte[1024];
            dataBuff[0] = 0;
            int varNum = 0;
            int dataBuffLen = 2;
            if (paramMap != null) {
                for(Iterator var9 = paramMap.entrySet().iterator(); var9.hasNext(); ++varNum) {
                    Map.Entry<String, String> entry = (Map.Entry)var9.next();
                    String mapKey = (String)entry.getKey();
                    String mapValue = (String)entry.getValue();
                    int size = mapKey.length();
                    dataBuff[dataBuffLen] = (byte)(size & 255);
                    ++dataBuffLen;
                    System.arraycopy(mapKey.getBytes(), 0, dataBuff, dataBuffLen, size);
                    dataBuffLen += size;
                    dataBuff[dataBuffLen] = 2;
                    ++dataBuffLen;
                    size = mapValue.length();
                    dataBuff[dataBuffLen] = (byte)(size & 255);
                    ++dataBuffLen;
                    System.arraycopy(mapValue.getBytes(), 0, dataBuff, dataBuffLen, size);
                    dataBuffLen += size;
                }
            }

            dataBuff[1] = (byte)(varNum & 255);
            int resFlag = X9ProtocolDeal.sendDataToX9(dataBuff, dataBuffLen, deviceId, folNum, 156, 0);
            if (resFlag == 0) {
                rd.setCode(0);
                rd.setMessage("发送数据成功");
            } else {
                rd.setMessage(String.format("发送失败，错误值：", resFlag));
            }
        } else if (dix == null) {
            rd.setMessage("X9控制器未进行初始化，不可进行任何操作");
        } else {
            rd.setMessage("X9控制器离线，不可进行任何操作");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public static ReturnData x9DeviceControlDeal(String deviceId, Integer cmd, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        DeviceInforX9Var.devX9InforMapLock.lock();
        DeviceInforX9 dix = (DeviceInforX9)DeviceInforX9Var.devX9InforMap.get(deviceId);
        if (dix != null && dix.getOnlineFlag() == 1) {
            String playId = dix.getPlayIds();
            int folNum = dix.getFolNum();
            dix.setFolNum(folNum + 1);
            DeviceInforX9Var.devX9InforMap.put(deviceId, dix);
            DeviceInforX9Var.devX9InforMapLock.unlock();
            byte[] dataBuff = null;
            int proCmd = -1;
            int playIdLen = playId.length();

            String ctrlKey;
            int sendDataBuffLen;
            int resFlag;
            try {
                String paramCheckStr;
                int dataBuffLen;
                int timeIntervalInt;
                int statusType;
                switch (cmd) {
                    case 1:
                        ctrlKey = (String)paramMap.get("switchVal");
                        if (ctrlKey != null) {
                            sendDataBuffLen = Integer.valueOf(ctrlKey);
                            if (sendDataBuffLen > -1 && sendDataBuffLen < 4) {
                                dataBuff = new byte[]{(byte)(sendDataBuffLen & 255)};
                                proCmd = 14;
                                break;
                            }

                            rd.setMessage("开关值参数范围：0 - 3");
                            break;
                        }

                        rd.setMessage("开关值参数必填，且参数范围：0 - 3");
                        break;
                    case 2:
                        String dimmValStr = (String)paramMap.get("dimmVal");
                        if (dimmValStr != null) {
                            resFlag = Integer.valueOf(dimmValStr);
                            if (resFlag > -1 && resFlag < 101) {
                                dataBuff = new byte[]{(byte)(resFlag & 255)};
                                proCmd = 13;
                                break;
                            }

                            rd.setMessage("调光值参数范围：0 - 100");
                            break;
                        }

                        rd.setMessage("调光值参数必填，且参数范围：0 - 100");
                        break;
                    case 3:
                        String planId = (String)paramMap.get("planId");
                        if (planId != null) {
                            int planIdLen = planId.length();
                            dataBuffLen = 3 + planIdLen + playIdLen;
                            dataBuff = new byte[dataBuffLen];
                            dataBuff[0] = 1;
                            dataBuff[1] = (byte)(playIdLen & 255);
                            System.arraycopy(playId.getBytes(), 0, dataBuff, 2, playIdLen);
                            dataBuff[2 + playIdLen] = (byte)(planIdLen & 255);
                            playIdLen += 3;
                            System.arraycopy(planId.getBytes(), 0, dataBuff, playIdLen, planIdLen);
                            proCmd = 16;
                        } else {
                            rd.setMessage("播放计划ID必填");
                        }
                        break;
                    case 4:
                        String programId = (String)paramMap.get("programId");
                        String playTypeStr = (String)paramMap.get("playType");
                        String startTime = (String)paramMap.get("startTime");
                        String oldPlayActionStr = (String)paramMap.get("oldPlayAction");
                        String playTimeStr = (String)paramMap.get("playTime");
                        paramCheckStr = urgentParamCheck(programId, playTypeStr, startTime, oldPlayActionStr, playTimeStr);
                        if (paramCheckStr == null) {
                            int playType = Integer.valueOf(playTypeStr);
                            int oldPlayAction = Integer.valueOf(oldPlayActionStr);
                            int playTime = Integer.valueOf(playTimeStr);
                            timeIntervalInt = programId.length();
                            dataBuffLen = 18 + timeIntervalInt + playIdLen;
                            dataBuff = new byte[dataBuffLen];
                            dataBuff[0] = 1;
                            dataBuff[1] = (byte)(playIdLen & 255);
                            System.arraycopy(playId.getBytes(), 0, dataBuff, 2, playIdLen);
                            dataBuff[2 + playIdLen] = (byte)(timeIntervalInt & 255);
                            playIdLen += 3;
                            System.arraycopy(programId.getBytes(), 0, dataBuff, playIdLen, timeIntervalInt);
                            playIdLen += timeIntervalInt;
                            dataBuff[playIdLen] = (byte)(playType & 255);
                            ++playIdLen;
                            byte[] timeByte = ProtocolPackage.timeStringToX9Byte(startTime);
                            System.arraycopy(timeByte, 0, dataBuff, playIdLen, 9);
                            playIdLen += 9;
                            dataBuff[playIdLen] = (byte)(oldPlayAction & 255);
                            ++playIdLen;
                            byte[] playTimeByte = ProtocolPackage.addIntToByte(playTime, 4);
                            System.arraycopy(playTimeByte, 0, dataBuff, playIdLen, 4);
                            proCmd = 20;
                        } else {
                            rd.setMessage(paramCheckStr);
                        }
                        break;
                    case 5:
                        String queryFalgStr = (String)paramMap.get("queryFalg");
                        String timeIntervalStr = (String)paramMap.get("timeInterval");
                        String percentageStr = (String)paramMap.get("percentage");
                        paramCheckStr = snapShotParamCheck(timeIntervalStr, percentageStr);
                        if (paramCheckStr == null) {
                            timeIntervalInt = Integer.valueOf(timeIntervalStr);
                            statusType = Integer.valueOf(percentageStr);
                            int queryFalg = 0;
                            if (queryFalgStr != null) {
                                queryFalg = Integer.valueOf(queryFalgStr);
                            }

                            dataBuffLen = 4 + playIdLen;
                            dataBuff = new byte[dataBuffLen];
                            dataBuff[0] = (byte)(playIdLen & 255);
                            System.arraycopy(playId.getBytes(), 0, dataBuff, 1, playIdLen);
                            dataBuff[dataBuffLen - 3] = (byte)(timeIntervalInt >> 8 & 255);
                            dataBuff[dataBuffLen - 2] = (byte)(timeIntervalInt & 255);
                            dataBuff[dataBuffLen - 1] = (byte)(statusType & 255);
                            if (queryFalg == 0) {
                                proCmd = 27;
                            } else {
                                proCmd = 19;
                            }
                        } else {
                            rd.setMessage(paramCheckStr);
                        }
                        break;
                    case 6:
                        String statusTypeStr = (String)paramMap.get("statusType");
                        if (statusTypeStr != null) {
                            statusType = Integer.valueOf(statusTypeStr);
                            if (statusType > -1 && statusType < 14) {
                                dataBuff = new byte[]{1, (byte)(statusType & 255)};
                                proCmd = 8;
                                break;
                            }

                            rd.setMessage("状态类型取值范围：0 - 13");
                            break;
                        }

                        rd.setMessage("状态类型必填");
                        break;
                    case 7:
                        dataBuffLen = 1 + playIdLen;
                        dataBuff = new byte[dataBuffLen];
                        dataBuff[0] = (byte)(playIdLen & 255);
                        System.arraycopy(playId.getBytes(), 0, dataBuff, 1, playIdLen);
                        proCmd = 21;
                        break;
                    case 8:
                        dataBuff = x9UtcTimeToByte();
                        proCmd = 6;
                        break;
                    case 9:
                        proCmd = 38;
                        break;
                    case 10:
                        String sourceTypeStr = (String)paramMap.get("sourceType");
                        String channelStr = (String)paramMap.get("channel");
                        String uploadStr = (String)paramMap.get("upload");
                        String sourceStr = (String)paramMap.get("source");
                        paramCheckStr = environmentParamCheck(sourceTypeStr, channelStr, uploadStr, sourceStr);
                        if (paramCheckStr == null) {
                            int sourceType = Integer.valueOf(sourceTypeStr);
                            int channel = Integer.valueOf(channelStr);
                            int upload = Integer.valueOf(uploadStr);
                            int sourceStrLen = 0;
                            if (sourceStr != null) {
                                sourceStrLen = sourceStr.length();
                            }

                            sourceStrLen += 4;
                            dataBuffLen = 3 + sourceStrLen;
                            dataBuff = new byte[dataBuffLen];
                            dataBuff[0] = 8;
                            dataBuff[1] = (byte)(sourceStrLen >> 8 & 255);
                            dataBuff[2] = (byte)(sourceStrLen & 255);
                            dataBuff[3] = (byte)(sourceType & 255);
                            dataBuff[4] = (byte)(channel & 255);
                            dataBuff[5] = (byte)(upload & 255);
                            dataBuff[6] = (byte)(sourceStrLen & 255);
                            if (sourceStrLen > 4) {
                                sourceStrLen = sourceStr.length();
                                System.arraycopy(sourceStr.getBytes(), 0, dataBuff, 7, sourceStrLen);
                            }

                            proCmd = 24;
                        } else {
                            rd.setMessage(paramCheckStr);
                        }
                        break;
                    case 11:
                        dataBuffLen = playIdLen + 10;
                        dataBuff = new byte[dataBuffLen];
                        dataBuff[0] = 1;
                        dataBuff[1] = (byte)(playIdLen & 255);
                        System.arraycopy(playId.getBytes(), 0, dataBuff, 2, playIdLen);
                        dataBuff[2 + playIdLen] = 0;
                        dataBuff[3 + playIdLen] = 0;
                        dataBuff[4 + playIdLen] = 0;
                        dataBuff[5 + playIdLen] = 0;
                        dataBuff[6 + playIdLen] = 0;
                        dataBuff[7 + playIdLen] = 0;
                        dataBuff[8 + playIdLen] = 0;
                        dataBuff[9 + playIdLen] = 0;
                        proCmd = 35;
                        break;
                    case 12:
                        String taskId = (String)paramMap.get("taskId");
                        String upgradeFile = (String)paramMap.get("upgradeFile");
                        String upgradeType = (String)paramMap.get("upgradeType");
                        String upgradeTime = (String)paramMap.get("upgradeTime");
                        paramCheckStr = x9UpgradeParamCheck(taskId, upgradeFile, upgradeType, upgradeTime);
                        if (paramCheckStr == null) {
                            int upgradeFileLen = upgradeFile.length();
                            int taskIdLen = taskId.length();
                            int upgradeTypeInt = Integer.valueOf(upgradeType);
                            dataBuffLen = 12 + upgradeFileLen + taskIdLen;
                            dataBuff = new byte[dataBuffLen];
                            dataBuff[0] = (byte)(taskIdLen & 255);
                            System.arraycopy(taskId.getBytes(), 0, dataBuff, 1, taskIdLen);
                            ++taskIdLen;
                            dataBuff[taskIdLen] = (byte)(upgradeFileLen & 255);
                            ++taskIdLen;
                            System.arraycopy(upgradeFile.getBytes(), 0, dataBuff, taskIdLen, upgradeFileLen);
                            taskIdLen += upgradeFileLen;
                            dataBuff[taskIdLen] = (byte)(upgradeTypeInt & 255);
                            if (upgradeTypeInt == 1) {
                                ++taskIdLen;
                                byte[] upgradeTimeByte = ProtocolPackage.timeStringToX9Byte(upgradeTime);
                                System.arraycopy(upgradeTimeByte, 0, dataBuff, taskIdLen, 9);
                            }

                            proCmd = 41;
                        } else {
                            rd.setMessage(paramCheckStr);
                        }
                        break;
                    default:
                        rd.setMessage("不支持的命令字，请查看说明文档");
                }
            } catch (Exception var38) {
                var38.printStackTrace();
                rd.setMessage("库封装协议异常");
            }

            if (dataBuff != null || cmd == 9) {
                ctrlKey = String.format("%s%05d", deviceId, folNum);
                DeviceInforX9Var.devX9ControlMap.put(ctrlKey, -1);

                try {
                    sendDataBuffLen = 0;
                    if (dataBuff != null) {
                        sendDataBuffLen = dataBuff.length;
                    }

                    resFlag = X9ProtocolDeal.sendDataToX9(dataBuff, sendDataBuffLen, deviceId, folNum, proCmd, 1);
                    if (resFlag != 0) {
                        rd.setMessage(String.format("发送失败，错误值：", resFlag));
                    } else {
                        long waitTime = 500L;

                        int waitNum;
                        for(waitNum = 1; waitNum < 5; ++waitNum) {
                            try {
                                Thread.sleep(waitTime * (long)waitNum);
                            } catch (InterruptedException var36) {
                                var36.printStackTrace();
                            }

                            Integer ctrlRes = (Integer)DeviceInforX9Var.devX9ControlMap.get(ctrlKey);
                            if (ctrlRes != -1) {
                                if (ctrlRes == 0) {
                                    rd.setCode(0);
                                    rd.setMessage("控制成功");
                                } else {
                                    rd.setMessage(String.format("控制失败，设备返回值：", ctrlRes));
                                }
                                break;
                            }
                        }

                        if (waitNum >= 5) {
                            rd.setMessage("等待控制结果超时，请重试");
                        }
                    }
                } catch (Exception var37) {
                    var37.printStackTrace();
                    rd.setMessage("库发送协议异常");
                }

                DeviceInforX9Var.devX9ControlMap.remove(ctrlKey);
            }
        } else {
            DeviceInforX9Var.devX9InforMapLock.unlock();
            if (dix == null) {
                rd.setMessage("X9控制器未进行初始化，不可进行任何操作");
            } else {
                rd.setMessage("X9控制器离线，不可进行任何操作");
            }
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }
}
